package com.ssy.system.config;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.DelegatingFilterProxy;

import com.ssy.system.realm.UserRealm;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import lombok.Data;

/**
 * @author sunshuaiyong
 * @ClassName ShiroConfiguration
 * @description: Shiro配置类
 * @date 2021/10/29 10:35
 */
@Data
@Configuration
public class ShiroConfiguration {

    private String hashAlgorithmName = "md5";
    private int hashIterations = 4;
    private String targetBeanName = "shiroFilter";
    private boolean targetFilterLifecycle = true;
    private String loginUrl = "/";
    private String unauthorizedUrl = "/unauthorized.html";

    //放行的路径 "/login/login*", "/index.html*", "/login.html*", "/resources/**"
    private String[] anonUrls = {"/index.html","/login/**", "/admin/**", "/component/**", "/config/**"};

    //拦截的路径 /**
    private String[] authcUrls = {"/**"};

    /**
     * 声明凭证匹配器
     *
     * @return
     */
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher() {
        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
        // 注入加密方式
        credentialsMatcher.setHashAlgorithmName(hashAlgorithmName);
        // 注入散列次数
        credentialsMatcher.setHashIterations(hashIterations);
        return credentialsMatcher;
    }

    /**
     * 声明userRealm
     *
     * @param credentialsMatcher 声明凭证匹配器
     * @return
     */
    @Bean
    public UserRealm usrRealm(HashedCredentialsMatcher credentialsMatcher) {
        UserRealm userRealm = new UserRealm();
        // 注入凭证匹配器
        userRealm.setCredentialsMatcher(credentialsMatcher);
        return userRealm;
    }

    /**
     * 声明安全管理器
     *
     * @param userRealm
     * @return
     */
    @Bean
    public SecurityManager securityManager(UserRealm userRealm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        // 注入realm
        securityManager.setRealm(userRealm);
        return securityManager;
    }


    /**
     * 配置shiro的代理过滤器
     *
     * @return
     */
    @Bean
    public FilterRegistrationBean<DelegatingFilterProxy> filterRegistrationBeanDelegatingFilterProxy() {
        //创建注册器
        FilterRegistrationBean<DelegatingFilterProxy> registrationBean = new FilterRegistrationBean<DelegatingFilterProxy>();
        //创建代理过滤器
        DelegatingFilterProxy proxy = new DelegatingFilterProxy();
        //设置过滤器的参数
        proxy.setTargetBeanName(targetBeanName);
        proxy.setTargetFilterLifecycle(targetFilterLifecycle);
        //注册
        registrationBean.setFilter(proxy);
        Collection<String> servletNames = new ArrayList<String>();
        servletNames.add(DispatcherServletAutoConfiguration.DEFAULT_DISPATCHER_SERVLET_BEAN_NAME);
        registrationBean.setServletNames(servletNames);
        return registrationBean;
    }


    /**
     * 创建ShiroFilterFactoryBean
     *
     * @param securityManager
     * @return
     */
    @Bean(value = "shiroFilter")
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
        //注入安全管理器
        factoryBean.setSecurityManager(securityManager);
        //设置非登陆跳转的页面
        factoryBean.setLoginUrl(loginUrl);
        //未授权的跳转页
        factoryBean.setUnauthorizedUrl(unauthorizedUrl);
        Map<String, String> filterChainDefinitionMap = new HashMap<String, String>();
        //设置放行的url
        if (anonUrls != null && anonUrls.length > 0) {
            for (String url : anonUrls) {
                filterChainDefinitionMap.put(url, "anon");
            }
        }
        //设置拦截的url
        if (authcUrls != null && authcUrls.length > 0) {
            for (String url : authcUrls) {
                filterChainDefinitionMap.put(url, "authc");
            }
        }
        //设置过滤器
        factoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return factoryBean;
    }

    /**
     * 在html页面引用shiro标签
     *
     * @return
     */
    @Bean
    public ShiroDialect shiroDialect() {
        return new ShiroDialect();
    }


    /****加入对注解的支持******/
    /**
     * @param securityManager
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

    @Bean
    public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        advisorAutoProxyCreator.setProxyTargetClass(true);
        return advisorAutoProxyCreator;
    }


}
